package com.spzx.cart.service.impl;

import com.spzx.cart.api.RemoteCartService;
import com.spzx.cart.api.domain.CartInfo;
import com.spzx.cart.service.ICartService;
import com.spzx.common.core.constant.SecurityConstants;
import com.spzx.common.core.context.SecurityContextHolder;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.core.web.domain.AjaxResult;
import com.spzx.common.security.annotation.RequiresLogin;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.vo.SkuPrice;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@Slf4j
public class CartServiceImpl implements ICartService {

    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    private RemoteProductService remoteProductService;

    //定义一个key
    private String getCartkey(Long userID) {
        return "user:card:" + userID;
    }

    @Override
    public void addToCart(Long skuID, Integer skuNum) {
        //获取当前登录的userId
        Long userId = SecurityContextHolder.getUserId();
        //1.创建一个购物车hash解构的key  user: 用户ID :cart
        String cartkey = getCartkey(userId);
        //2.创建hash结构绑定操作对象
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(cartkey);
        //4.判断用户购物车是否有商品,如果有数量进行累加,如果没有进行商品添加
        String hashKey = skuID.toString();
        //初始值为99
        Integer threshold = 99;
        if (hashOps.hasKey(hashKey)) {
            CartInfo cartInfo = hashOps.get(hashKey);
            int totalcount = cartInfo.getSkuNum() + skuNum;
            //是否大于初始值,固定最大值为99
            cartInfo.setSkuNum(totalcount > threshold ? threshold : totalcount);
            hashOps.put(hashKey, cartInfo);

        } else {
            //3.判断购物车商品种类,总数大于五十件
            Long count = hashOps.size();
            if (++count > 50) {
                throw new RuntimeException("商品种类超过上限");
            }
            //4.购物车没有该商品,构建购物车对象,存入redis
            CartInfo cartInfo = new CartInfo();
            cartInfo.setSkuId(userId);
            cartInfo.setSkuNum(skuNum > threshold ? threshold : skuNum);
            cartInfo.setUpdateTime(new Date());
            cartInfo.setCreateTime(new Date());
            //4.1远程调取商品服务,获取商品基本信息
            R<ProductSku> productSkuResult = remoteProductService.getProductSku(skuID, SecurityConstants.INNER);

            if (R.FAIL == productSkuResult.getCode()) {
                throw new ServiceException(productSkuResult.getMsg());
            }
            ProductSku productSku = productSkuResult.getData();
            cartInfo.setSkuId(skuID);
            cartInfo.setSkuName(productSku.getSkuName());     //sku名称
            cartInfo.setThumbImg(productSku.getThumbImg());  //图片文件

            //4.2远程调取商品服务获取商品事实价格
            R<SkuPrice> skuPriceResult = remoteProductService.getSkuPrice(skuID, SecurityConstants.INNER);
            //获取的状态码为失败
            if (R.FAIL == skuPriceResult.getCode()) {
                throw new ServiceException(skuPriceResult.getMsg());
            }
            SkuPrice skuPrice = skuPriceResult.getData();
            cartInfo.setCartPrice(skuPrice.getSalePrice());
            cartInfo.setSkuPrice(skuPrice.getSalePrice());

            //4.3 将购物车商品存入redis中
            hashOps.put(hashKey, cartInfo);
        }
    }

    @Override
    public List<CartInfo> getCartCheckedList(Long userId) {
        List<CartInfo> cartInfoList = new ArrayList<>();

        String cartkey = this.getCartkey(userId);
        List<CartInfo> cartCachInfoList = redisTemplate.opsForHash().values(cartkey);
        if (!CollectionUtils.isEmpty(cartCachInfoList)) {
            for (CartInfo cartInfo : cartCachInfoList) {
                //获取选中的商品
                if (cartInfo.getIsChecked().intValue() == 1) {
                    cartInfoList.add(cartInfo);
                }
            }
        }
        return cartInfoList;

    }

    @Override
    public void clearCart() {
        //获取当前登录用户id
        Long userId = SecurityContextHolder.getUserId();
        String cartkey = getCartkey(userId);
        //获取缓存对象
        redisTemplate.delete(cartkey);
    }

    @Override
    public void allCheckCart(Integer isChecked) {
        //获取当前用户登录id
        Long userId = SecurityContextHolder.getUserId();
        String cartkey = getCartkey(userId);
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartkey);
        List<CartInfo> cartInfoList = hashOperations.values();
        cartInfoList.forEach(itme -> {
            CartInfo cartInfoUpd = hashOperations.get(itme.getSkuId().toString());
            cartInfoUpd.setIsChecked(isChecked);
            //更新缓存
            hashOperations.put(itme.getSkuId().toString(), cartInfoUpd);
        });
    }

    @Override
    public void checkCart(Long skuId, Integer isChecked) {
        //获取登录id
        Long userId = SecurityContextHolder.getUserId();
        //修改缓存
        String cartkey = this.getCartkey(userId);
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartkey);
        //获取用户选择的商品
        if (hashOperations.hasKey(skuId.toString())) {
            CartInfo cartInfoUpd = hashOperations.get(skuId.toString());
            //写缓存
            cartInfoUpd.setIsChecked(isChecked);
            //更新缓存
            hashOperations.put(skuId.toString(), cartInfoUpd);
        }
    }

    @Override
    public void deleteCart(Long skuId) {
        //获取当前登录用户的id
        Long userId = SecurityContextHolder.getUserId();
        String cartkey = getCartkey(userId);
        //获取缓存对象
        BoundHashOperations<String, String, CartInfo> hashOperations = redisTemplate.boundHashOps(cartkey);
        hashOperations.delete(skuId.toString());
    }

    @Override
    public List<CartInfo> getCartList() {
        //获取当前登录的id
        Long userId = SecurityContextHolder.getUserId();
        String cartkey = this.getCartkey(userId);
        //获取数据
        List<CartInfo> cartInfoList = redisTemplate.opsForHash().values(cartkey);
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            List<CartInfo> inforList = cartInfoList.stream()
                    .sorted((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()))
                    .collect(Collectors.toList());

            //skuId列表
            List<Long> skuIdList =
                    inforList.stream().map(CartInfo::getSkuId).collect(Collectors.toList());
            //查询商品的实时价格
            R<List<SkuPrice>> SkuPriceListResult = remoteProductService.getSkuPriceList(skuIdList, SecurityConstants.INNER);
            if (R.FAIL == SkuPriceListResult.getCode()) {
                throw new ServiceException(SkuPriceListResult.getMsg());
            }
            Map<Long, BigDecimal> skuIdToPriceMap =
                    SkuPriceListResult.getData().stream().collect(Collectors.toMap(SkuPrice::getSkuId, SkuPrice::getSalePrice));
            inforList.forEach(item -> {
                //设置实时价格
                item.setSkuPrice(skuIdToPriceMap.get(item.getSkuId()));
            });
            return inforList;
        }
        return new ArrayList<>();

    }

    @Override
    public Boolean updateCartPrice(Long userId) {
        String cartkey = getCartkey(userId);
        BoundHashOperations<String,String,CartInfo> hashOperations = redisTemplate.boundHashOps(cartkey);
        List<CartInfo> cartCachInfoList = hashOperations.values();
        if (!CollectionUtils.isEmpty(cartCachInfoList)){
            for (CartInfo cartInfo : cartCachInfoList) {
                if (cartInfo.getIsChecked().intValue()==1){
                    SkuPrice skuPrice = remoteProductService.getSkuPrice(cartInfo.getSkuId(), SecurityConstants.INNER).getData();
                    cartInfo.setSkuPrice(skuPrice.getSalePrice());
                    cartInfo.setCartPrice(skuPrice.getSalePrice());
                    hashOperations.put(cartInfo.getSkuPrice().toString(),cartInfo);
                }
            }
        }
      return true;
    }

    @Override
    public Boolean deleteCartCheckedList(Long userId) {
        String cartkey = getCartkey(userId);
        BoundHashOperations<String,String,CartInfo> boundHashOperations = redisTemplate.boundHashOps(cartkey);
        List<CartInfo> cartInfoList = boundHashOperations.values();
        if (!CollectionUtils.isEmpty(cartInfoList)){
            for (CartInfo cartInfo : cartInfoList) {
               if (cartInfo.getIsChecked().intValue()==1){
                   boundHashOperations.delete(cartInfo.getSkuId().toString());
               }
            }
        }
        return true;
    }
}